import { Byte } from '../../api/io/Byte';
import { ITimer } from '../../api/timer/ITimer';
import { IAsync } from '../../api/event/IAsync';



/**随机事件详情属性枚举*/
export const enum E_RandomEventItem {
	/**事件id*/
	EVENT_ID = 0,
	/**配置id*/
	CONFIG_ID = 1,
	/**状态*/
	STATUS = 2,
	/**类型*/
	RANDOM_EVENT_TYPE = 3,
	/**结束时间*/
	END_TIME = 5,
	/**刷新时间*/
	REFRESH_TIME = 6,
	/**随机任务id*/
	RANDOM_MISSION_CONFIG_ID = 7,
	/**枚举数量*/
	EnumCount = 8
}


/**随机事件详情*/
export class RandomEventItem {
	/**事件ID*/
	public static readonly EVENT_ID = 'STRUCT_DATA_RANDOM_EVENT_ITEM_EVENT_ID';
	/**整体更新事件ID（部分只需要监听整体变化）*/
	public static readonly TOTAL_EVENT_ID = 'STRUCT_DATA_RANDOM_EVENT_ITEM_TOTAL_EVENT_ID';
	/**缓存池*/
	private static POOL: RandomEventItem[] = [];

	/**创建入口*/
	public static create(json?: string): RandomEventItem {
		const c = this.POOL.pop() || new RandomEventItem();
		c._destroyed = false;
		c.resetProperty();
		if (json) {
			c.parse(json);
		}
		return c;
	}


	/**已释放*/
	protected _destroyed = false;
	/**事件id (uint32)*/
	protected _eventId: number;
	/**配置id (uint32)*/
	protected _configId: number;
	/**状态 (uint8)*/
	protected _status: number;
	/**类型 (uint16)*/
	protected _randomEventType: number;
	/**结束时间 (long)*/
	protected _endTime: number;
	/**刷新时间 (long)*/
	protected _refreshTime: number;
	/**随机任务id (uint32)*/
	protected _randomMissionConfigId: number;


	/**构建函数-私有，防止外部创建*/
	private constructor() {
	}


	/**释放*/
	public destroy(): void {
		if (this._destroyed) {
			return;
		}
		this._destroyed = true;
		this.resetProperty(true);
		if (RandomEventItem.POOL.indexOf(this) === -1) {
			RandomEventItem.POOL.push(this);
		}
	}

	/**事件id*/
	public get eventId() {
		return this._eventId;
	}


	/**事件id*/
	public set eventId(v: number) {
		this._eventId = v;
	}


	/**配置id*/
	public get configId() {
		return this._configId;
	}


	/**配置id*/
	public set configId(v: number) {
		this._configId = v;
	}


	/**状态*/
	public get status() {
		return this._status;
	}


	/**状态*/
	public set status(v: number) {
		this._status = v;
	}


	/**类型*/
	public get randomEventType() {
		return this._randomEventType;
	}


	/**类型*/
	public set randomEventType(v: number) {
		this._randomEventType = v;
	}


	/**结束时间*/
	public get endTime() {
		return this._endTime;
	}


	/**结束时间*/
	public set endTime(v: number) {
		this._endTime = v;
	}


	/**刷新时间*/
	public get refreshTime() {
		return this._refreshTime;
	}


	/**刷新时间*/
	public set refreshTime(v: number) {
		this._refreshTime = v;
	}


	/**随机任务id*/
	public get randomMissionConfigId() {
		return this._randomMissionConfigId;
	}


	/**随机任务id*/
	public set randomMissionConfigId(v: number) {
		this._randomMissionConfigId = v;
	}



	/**通过枚举获取值*/
	public getV(k: E_RandomEventItem): any {
		switch (k) {
			case E_RandomEventItem.EVENT_ID: return this._eventId;
			case E_RandomEventItem.CONFIG_ID: return this._configId;
			case E_RandomEventItem.STATUS: return this._status;
			case E_RandomEventItem.RANDOM_EVENT_TYPE: return this._randomEventType;
			case E_RandomEventItem.END_TIME: return this._endTime;
			case E_RandomEventItem.REFRESH_TIME: return this._refreshTime;
			case E_RandomEventItem.RANDOM_MISSION_CONFIG_ID: return this._randomMissionConfigId;
			default: return null;
		}
	}


	/**通过枚举设置值*/
	public setV(k: E_RandomEventItem, v: any): void {
		switch (k) {
			case E_RandomEventItem.EVENT_ID: this._eventId = v; break;
			case E_RandomEventItem.CONFIG_ID: this._configId = v; break;
			case E_RandomEventItem.STATUS: this._status = v; break;
			case E_RandomEventItem.RANDOM_EVENT_TYPE: this._randomEventType = v; break;
			case E_RandomEventItem.END_TIME: this._endTime = v; break;
			case E_RandomEventItem.REFRESH_TIME: this._refreshTime = v; break;
			case E_RandomEventItem.RANDOM_MISSION_CONFIG_ID: this._randomMissionConfigId = v; break;
			default: break;
		}
	}


	/**初始化*/
	public resetProperty(fromDestroy = false): void {
		//事件id
		this._eventId = 0;
		//配置id
		this._configId = 0;
		//状态
		this._status = 0;
		//类型
		this._randomEventType = 0;
		//结束时间
		this._endTime = 0;
		//刷新时间
		this._refreshTime = 0;
		//随机任务id
		this._randomMissionConfigId = 0;
	}


	/**序列化*/
	public stringify(toString: boolean): string | any {
		const json: any = {};
		if (this._eventId) {
			json.eventId = this._eventId;
		}
		if (this._configId) {
			json.configId = this._configId;
		}
		if (this._status) {
			json.status = this._status;
		}
		if (this._randomEventType) {
			json.randomEventType = this._randomEventType;
		}
		if (this._endTime) {
			json.endTime = this._endTime;
		}
		if (this._refreshTime) {
			json.refreshTime = this._refreshTime;
		}
		if (this._randomMissionConfigId) {
			json.randomMissionConfigId = this._randomMissionConfigId;
		}

		return toString ? JSON.stringify(json) : json;
	}


	/**反序列化*/
	public parse(jsonv: string | any): this {
		this.resetProperty();
		if (!jsonv) {
			return this;
		}
		const json = typeof (jsonv) === 'string' ? JSON.parse(jsonv) : jsonv;
		if (json.eventId) {
			this._eventId = json.eventId;
		}
		if (json.configId) {
			this._configId = json.configId;
		}
		if (json.status) {
			this._status = json.status;
		}
		if (json.randomEventType) {
			this._randomEventType = json.randomEventType;
		}
		if (json.endTime) {
			this._endTime = json.endTime;
		}
		if (json.refreshTime) {
			this._refreshTime = json.refreshTime;
		}
		if (json.randomMissionConfigId) {
			this._randomMissionConfigId = json.randomMissionConfigId;
		}
		return this;
	}


	/**序列化-二进制*/
	public toBytes(byte: Byte): void {
		if (!byte) {
			return;
		}
		byte.writeUint32(this._eventId);
		byte.writeUint32(this._configId);
		byte.writeUint8(this._status);
		byte.writeUint16(this._randomEventType);
		byte.writeLongNumber(this._endTime);
		byte.writeLongNumber(this._refreshTime);
		byte.writeUint32(this._randomMissionConfigId);
	}


	/**反序列化-二进制*/
	public fromBytes(byte: Byte): this {
		this.resetProperty();
		if (!byte) {
			return;
		}
		this._eventId = byte.readUint32();
		this._configId = byte.readUint32();
		this._status = byte.readUint8();
		this._randomEventType = byte.readUint16();
		this._endTime = byte.readLongNumber();
		this._refreshTime = byte.readLongNumber();
		this._randomMissionConfigId = byte.readUint32();
		return this;
	}


	/**克隆*/
	public clone(): RandomEventItem {
		const byte = Byte.createFromPool();
		this.toBytes(byte);
		byte.pos = 0;
		const clonev = RandomEventItem.create().fromBytes(byte);
		Byte.recoverToPool(byte);
		return clonev;
	}


	/**处理更新*/
	public processUpdate(jsonv: string): void {
		if (!jsonv) {
			return;
		}

		const eventID = RandomEventItem.EVENT_ID;
		const us = JSON.parse(jsonv);

		for (let i = 0, len = us.length; i < len;) {
			const idx = us[i];
			//事件id
			if (idx === E_RandomEventItem.EVENT_ID) {
				const oldv = this._eventId;
				this._eventId = us[i + 1];
				IAsync.dispatch(eventID, idx, this._eventId, oldv);
				i += 2;
				continue;
			}
			//配置id
			if (idx === E_RandomEventItem.CONFIG_ID) {
				const oldv = this._configId;
				this._configId = us[i + 1];
				IAsync.dispatch(eventID, idx, this._configId, oldv);
				i += 2;
				continue;
			}
			//状态
			if (idx === E_RandomEventItem.STATUS) {
				const oldv = this._status;
				this._status = us[i + 1];
				IAsync.dispatch(eventID, idx, this._status, oldv);
				i += 2;
				continue;
			}
			//类型
			if (idx === E_RandomEventItem.RANDOM_EVENT_TYPE) {
				const oldv = this._randomEventType;
				this._randomEventType = us[i + 1];
				IAsync.dispatch(eventID, idx, this._randomEventType, oldv);
				i += 2;
				continue;
			}
			//结束时间
			if (idx === E_RandomEventItem.END_TIME) {
				const oldv = this._endTime;
				this._endTime = us[i + 1];
				IAsync.dispatch(eventID, idx, this._endTime, oldv);
				i += 2;
				continue;
			}
			//刷新时间
			if (idx === E_RandomEventItem.REFRESH_TIME) {
				const oldv = this._refreshTime;
				this._refreshTime = us[i + 1];
				IAsync.dispatch(eventID, idx, this._refreshTime, oldv);
				i += 2;
				continue;
			}
			//随机任务id
			if (idx === E_RandomEventItem.RANDOM_MISSION_CONFIG_ID) {
				const oldv = this._randomMissionConfigId;
				this._randomMissionConfigId = us[i + 1];
				IAsync.dispatch(eventID, idx, this._randomMissionConfigId, oldv);
				i += 2;
				continue;
			}

			console.error('[Struct Data] can not find enum in RandomEventItem with idx = ' + idx + ', version maybe wrong.')
		}

		//全更事件
		ITimer.callLater(this, this.dispatchTotalUpdate);
	}


	/**比对不一致结果*/
	public getCompareInfo(other: RandomEventItem): string {
		if (!other) {
			return null;
		}

		const updates: any[] = [];

		if (this._eventId !== other._eventId) {
			updates.push(E_RandomEventItem.EVENT_ID, this._eventId);
		}
		if (this._configId !== other._configId) {
			updates.push(E_RandomEventItem.CONFIG_ID, this._configId);
		}
		if (this._status !== other._status) {
			updates.push(E_RandomEventItem.STATUS, this._status);
		}
		if (this._randomEventType !== other._randomEventType) {
			updates.push(E_RandomEventItem.RANDOM_EVENT_TYPE, this._randomEventType);
		}
		if (this._endTime !== other._endTime) {
			updates.push(E_RandomEventItem.END_TIME, this._endTime);
		}
		if (this._refreshTime !== other._refreshTime) {
			updates.push(E_RandomEventItem.REFRESH_TIME, this._refreshTime);
		}
		if (this._randomMissionConfigId !== other._randomMissionConfigId) {
			updates.push(E_RandomEventItem.RANDOM_MISSION_CONFIG_ID, this._randomMissionConfigId);
		}

		const jsonv = updates.length === 0 ? null : JSON.stringify(updates);
		return jsonv;
	}


	/**全部更新*/
	protected dispatchTotalUpdate(): void {
		IAsync.dispatch(RandomEventItem.TOTAL_EVENT_ID, this.getV(0));
	}

}
